/**************************************************************************
 * @name: pthread_kill.c
 * @brief: 学习线程的信号响应机制
 * @date: 2025/02/17
 * @author: boluzs@163.com
 * @note:   设计一个程序，要求程序中有3条子线程
 *          子线程A接收到SIGINT 信号时就输出自身的线程ID
 *          子线程B和子线程C则屏蔽该信号，运行程序并观察效果。
 * @version: 1.0.0
 * @Copyright (c) 2025 by boluzs@163.com, All Rights Reserved.
 **************************************************************************/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <stdlib.h>

#include <time.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
#include <bits/sigaction.h>

void signal_handler(int signum)
{
    printf("thread ID = %#x\n", pthread_self());
}

// 构造线程的回调函数 格式是固定的
void *threadA_handler(void *arg)
{
    signal(SIGINT, signal_handler);
    // 信号注册
    for (;;)
    {
        printf("A thread is running, threadA id = %#x\n", pthread_self());
        sleep(1);
    }
}

// 构造线程的回调函数 格式是固定的
void *threadB_handler(void *arg)
{
    for (;;)
    {
        printf("B thread is running, threadB id = %#x\n", pthread_self());
        sleep(1);
    }
}

// 构造线程的回调函数 格式是固定的
void *threadC_handler(void *arg)
{

    for (;;)
    {
        printf("C thread is running, threadC id = %#x\n", pthread_self());
        sleep(1);
    }
}

int main()
{

        pthread_t newthreadA_id = 0; // 用于记录创建的新线程的ID，可以理解为是线程的句柄
    pthread_t newthreadB_id = 0; // 用于记录创建的新线程的ID，可以理解为是线程的句柄
    pthread_t newthreadC_id = 0; // 用于记录创建的新线程的ID，可以理解为是线程的句柄

    // 1.创建新线程
    pthread_create(&newthreadA_id, NULL, threadA_handler, NULL);

    __sigset_t set;

    // 屏蔽 SIGINT 信号
    sigemptyset(&set);
    sigaddset(&set, SIGINT);
    if (pthread_sigmask(SIG_BLOCK, &set, NULL) != 0)
    {
        fprintf(stderr, "pthread_sigmask: error = [%s]\n", strerror(errno));
        exit(-1);
    }

    pthread_create(&newthreadB_id, NULL, threadB_handler, NULL);
    pthread_create(&newthreadC_id, NULL, threadC_handler, NULL);

    // 2.主线程等待子线程终止，主线程会进入阻塞
    pthread_join(newthreadA_id, NULL);
    pthread_join(newthreadB_id, NULL);
    pthread_join(newthreadC_id, NULL);

    return 0;
}
